;
; File     : X86_CDecl_Windows.s
; Created  : 5 May 2011
;
; Copyright © 2011 Matthew Wilson (mj. {my-surname} .uk {at} gmail.com)
;
; This program is free software: you can redistribute it and/or modify
; it under the terms of the GNU Lesser General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU Lesser General Public License for more details.
;
; You should have received a copy of the GNU Lesser General Public License
; along with this program.  If not, see <http:;;www.gnu.org/licenses/>.
;

.386
.MODEL FLAT

_TEXT SEGMENT

.CODE


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Call with 'n' arguments                                                      ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

dni_x86_cdecl_windows_call PROC

    ; Java JNI signature is:
    ;   int       fnptr
    ;   int       offset
    ;   <..>      arg0
    ;   <..>      arg1...
    ;   int       padding
    ;   int       padding
    ;
    ; Stack:
    ;            0    return address
    ;            4    JNIEnv*
    ;            8    jclass
    ;           12    function pointer
    ;           16    offset
    ;           20    arg0
    ;           24    arg1...
    ;   offset + 0    padding
    ;   offset + 4    padding

    ; retrieve the offset
    mov       ecx, dword ptr [ esp + 16 ]
    add       ecx, esp

    ; preserve ebp (parent call's base pointer)
    mov       dword ptr [ ecx ], ebp

    ; keep hold of the preserved words' location (ebp is preserved across calls)
    mov       ebp, ecx

    ; preserve the return address
    mov       ecx, dword ptr [ esp +  0 ]
    mov       dword ptr [ ebp + 4 ], ecx

    ; retrieve the function pointer
    mov       edx, dword ptr [ esp + 12 ]

    ; twiddle the stack pointer
    add       esp, 20

    ; call the function
    call      edx

    ; retrieve return address
    mov       ecx, dword ptr [ ebp + 4 ]

    ; clean the stack
    lea       esp, dword ptr [ ebp + 8 ]

    ; restore ebp
    mov       ebp, dword ptr [ ebp ]

    ; return
    jmp       ecx

dni_x86_cdecl_windows_call ENDP


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

_TEXT ENDS

END
